#ifndef __BUOLA_GUI_CATTACHMANAGER_H__
#define __BUOLA_GUI_CATTACHMANAGER_H__

#include <buola/gui/cwindow.h>

#include <unordered_map>

namespace buola { namespace gui {

///\addtogroup layout
///@{

///////////////////////////////////////////////////////////////////////////

/// attach widgets to the edge of a window

///
///
///
///////////////////////////////////////////////////////////////////////////

class CAttachManager
{
public:
    class SSaveHelper
    {
    public:
        virtual ~SSaveHelper() {}

        virtual PWindow NameToWindow(const std::wstring &pName)=0;
        virtual std::wstring WindowToName(const PWindow &pWindow)=0;
    };

    class SDecoration;
    class SResizeCorner;
    class STab;

    struct SRelocation;
    struct SPart;
    struct SSplit;
    struct SResizeSplit;
    struct SHSplit;
    struct SVSplit;
    struct SScrollSplit;
    struct SCSplit;
    struct STabSplit;
    struct SRoot;
    struct SClient;
    struct SAttachment;

public:
////////////////////////////////
// constructor and destructor
//
    CAttachManager(const PWindow &pWindow);
    ~CAttachManager();

public:
////////////////////////////////////////////////////////////////
////////////////////////// interface ///////////////////////////
////////////////////////////////////////////////////////////////
//attachments
    void Attach(const PWindow &pWin,EAttachPlace pPlace,EAttachFlags pFlags);
    void AttachRelative(const PWindow &pWin,EAttachRelative pRel,const PWindow &pOther,EAttachFlags pFlags);
    void AttachScroll(const PWindow &pH,const PWindow &pV,EAttachPlace pPlace);
    void Detach(const PWindow &pWin);
    void ResizeAttachBy(const PWindow &pWin,const CSize_d &pResize);
    void Undock(const PWindow &pWin);

    std::string SaveState(SSaveHelper*);
    void RestoreState(SSaveHelper*,const std::string &pSaved);

///////////////////////////////////////////////////////////////
////////////////////////// internal ///////////////////////////
///////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////
////////////////// event handlers ///////////////////
/////////////////////////////////////////////////////
    void OnExpose(const CExposeEvent &pE);
    void OnChild(const PWindow &pChild,int pEvent);
    void OnTitleChanged();

    CRect_d DoLayout();
    
    const PWindow& Window()   {   return mWindow; }

private:
////////////////////////////////////////
//////////// internal data /////////////
////////////////////////////////////////

//attachments
    PWindow mWindow;
    SRoot *mRoot;
    SPart *mClient;
    std::unordered_map<PWindow,SAttachment*> mAttachments;

    friend struct SHandle;
    friend struct SSplit;
};

///@}

/*namespace gui*/ } /*namespace buola*/ }

#endif
